using System;
using UnityEngine;

namespace CGF
{
    public static class AndroidStatusBarHelper
    {
        public enum StatusTextStyle
        {
            Dark,
            Light
        }

        // Original Android flags
        private const int SYSTEM_UI_FLAG_LAYOUT_STABLE = 256;
        private const int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024;
        private const int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;

        private static int FLAG_FULLSCREEN = 0x00000400;
        private static int FLAG_FORCE_NOT_FULLSCREEN = 0x00000800;
        private static int FLAG_LAYOUT_IN_SCREEN = 0x00000100;
        private static int FLAG_TRANSLUCENT_STATUS = 0x04000000;
        private static int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000;
        private static uint FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000;
        
        //显示状态栏并设置背景颜色和文字样式
        //iOS平台在 Project Settings - Other Settings - Resolustion And Presentations - Status Bat 里配置
        public static void SetStatusBarColor(StatusTextStyle statusTextStyle, Color bgColor)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            clearFlags(FLAG_FULLSCREEN | FLAG_TRANSLUCENT_STATUS);
            Screen.fullScreen = false;
            setFlags(FLAG_FORCE_NOT_FULLSCREEN, FLAG_FORCE_NOT_FULLSCREEN);
            setStatusBarColor(ConvertColorToAndroid(bgColor));
            //状态栏已经不透明，但Unity无法避开状态栏，只能通过Canvas的Top设置主动避开状态栏高度（使用Screen.safeArea.size）
            // 设置文字颜色
            int systemUiVisibility = 0;
            if (statusTextStyle == StatusTextStyle.Dark)
            {
                systemUiVisibility |= SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            }
            setSystemUiVisibility(systemUiVisibility);
#endif
        }
        
        //显示背景透明的状态栏并设置文字样式
        //iOS平台在 Project Settings - Other Settings - Resolustion And Presentations - Status Bat 里配置
        public static void SetStatusBarTransparent(StatusTextStyle statusTextStyle)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            clearFlags(FLAG_FULLSCREEN | FLAG_TRANSLUCENT_STATUS);
            Screen.fullScreen = false;
            setFlags((int)FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, -1);
            int systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE;
            setStatusBarColor(0);
            // 设置文字颜色
            if (statusTextStyle == StatusTextStyle.Dark)
            {
                systemUiVisibility |= SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            }
            setSystemUiVisibility(systemUiVisibility);
#endif
        }

        //设置背景颜色
        private static void setStatusBarColor(int color)
        {
            runOnAndroidUiThread(() =>
            {
                using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
                    {
                        using (var window = activity.Call<AndroidJavaObject>("getWindow"))
                        {
                            window.Call("setStatusBarColor", color);
                        }
                    }
                }
            });
        }
        
        private static int ConvertColorToAndroid(Color color)
        {
            Color32 c = color;
            return (c.a << 24) | (c.r << 16) | (c.g << 8) | c.b;
        }

        private static void runOnAndroidUiThread(Action target)
        {
            using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            {
                using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
                {
                    activity.Call("runOnUiThread", new AndroidJavaRunnable(target));
                }
            }
        }

        private static void clearFlags(int flags)
        {
            runOnAndroidUiThread(() =>
            {
                using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
                    {
                        using (var window = activity.Call<AndroidJavaObject>("getWindow"))
                        {
                            window.Call("clearFlags", flags);
                        }
                    }
                }
            });
        }

        private static void setSystemUiVisibility(int systemUiVisibilityValue)
        {
            runOnAndroidUiThread(() =>
            {
                using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
                    {
                        using (var window = activity.Call<AndroidJavaObject>("getWindow"))
                        {
                            using (var view = window.Call<AndroidJavaObject>("getDecorView"))
                            {
                                view.Call("setSystemUiVisibility", systemUiVisibilityValue);
                            }
                        }
                    }
                }
            });
        }

        private static void setFlags(int flags, int mask)
        {
            runOnAndroidUiThread(() =>
            {
                using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
                    {
                        using (var window = activity.Call<AndroidJavaObject>("getWindow"))
                        {
                            window.Call("setFlags", flags, mask);
                        }
                    }
                }
            });
        }

        private static void addFlags(int flags)
        {
            runOnAndroidUiThread(() =>
            {
                using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
                    {
                        using (var window = activity.Call<AndroidJavaObject>("getWindow"))
                        {
                            window.Call("addFlags", flags);
                        }
                    }
                }
            });
        }
    }
}